class NotificationWebSocket {
  private static instance: NotificationWebSocket;
  private socket: WebSocket | null = null;
  private reconnectTimeout: number = 2000; // 重连间隔时间
  private maxReconnectAttempts: number = 5; // 最大重连次数
  private reconnectAttempts: number = 0;
  private handlers: {[key: string]: ((data: any) => void)[]} = {};
  private connecting: boolean = false; // 添加连接状态标记

  private constructor() {}

  public static getInstance(): NotificationWebSocket {
    if (!NotificationWebSocket.instance) {
      NotificationWebSocket.instance = new NotificationWebSocket();
    }
    return NotificationWebSocket.instance;
  }

  // 连接WebSocket
  public connect(userId: number): void {
    if (!userId) {
      console.error('无法连接WebSocket: 用户ID无效');
      return;
    }
    
    // 如果已经在连接中或已连接，则不重复连接
    if (this.connecting || (this.socket && this.socket.readyState <= WebSocket.OPEN)) {
      console.log('WebSocket已经在连接中或已连接');
      return;
    }

    this.connecting = true;
    
    // 关闭之前的连接
    this.close();

    // 修改WebSocket连接URL为正确的格式
    const wsUrl = `ws://${import.meta.env.VITE_BASE_URL.replace('http://', '')}/websocket/notification/${userId}`;
    
    console.log('正在连接WebSocket，URL:', wsUrl);

    try {
      this.socket = new WebSocket(wsUrl);

      this.socket.onopen = () => {
        console.log('WebSocket连接已建立，用户ID:', userId);
        this.reconnectAttempts = 0; // 连接成功，重置重连计数
        this.connecting = false;
      };

      this.socket.onmessage = (event) => {
        try {
          console.log('收到WebSocket消息:', event.data);
          const data = JSON.parse(event.data);
          // 触发对应类型的处理函数
          if (data.type && this.handlers[data.type]) {
            this.handlers[data.type].forEach(handler => handler(data));
          }
          // 触发通用处理函数
          if (this.handlers['all']) {
            this.handlers['all'].forEach(handler => handler(data));
          }
        } catch (error) {
          console.error('解析WebSocket消息失败:', error);
        }
      };

      this.socket.onclose = (event) => {
        console.log('WebSocket连接已关闭，代码:', event.code, '原因:', event.reason);
        this.socket = null;
        this.connecting = false;
        
        // 只有在不是主动关闭的情况下才尝试重连
        if (event.code !== 1000 && this.reconnectAttempts < this.maxReconnectAttempts) {
          this.reconnectAttempts++;
          console.log(`尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
          setTimeout(() => {
            this.connect(userId);
          }, this.reconnectTimeout);
        }
      };

      this.socket.onerror = (error) => {
        console.error('WebSocket错误:', error);
        this.connecting = false;
      };
    } catch (error) {
      console.error('创建WebSocket连接失败:', error);
      this.connecting = false;
      
      // 尝试重连
      if (this.reconnectAttempts < this.maxReconnectAttempts) {
        this.reconnectAttempts++;
        console.log(`连接失败，尝试重连 (${this.reconnectAttempts}/${this.maxReconnectAttempts})...`);
        setTimeout(() => {
          this.connect(userId);
        }, this.reconnectTimeout);
      }
    }
  }

  // 关闭连接
  public close(): void {
    try {
      if (this.socket) {
        // 设置为正常关闭，避免触发重连
        this.socket.close(1000, "正常关闭");
        this.socket = null;
      }
      this.connecting = false;
    } catch (error) {
      console.error('关闭WebSocket连接出错:', error);
    }
  }

  // 添加消息处理器
  public on(type: string, handler: (data: any) => void): void {
    if (!this.handlers[type]) {
      this.handlers[type] = [];
    }
    this.handlers[type].push(handler);
  }

  // 移除消息处理器
  public off(type: string, handler: (data: any) => void): void {
    if (this.handlers[type]) {
      this.handlers[type] = this.handlers[type].filter(h => h !== handler);
    }
  }

  // 发送消息
  public send(data: any): void {
    if (this.socket && this.socket.readyState === WebSocket.OPEN) {
      this.socket.send(JSON.stringify(data));
    } else {
      console.error('WebSocket未连接，无法发送消息');
    }
  }
  
  // 检查连接状态
  public isConnected(): boolean {
    return this.socket !== null && this.socket.readyState === WebSocket.OPEN;
  }
}

export default NotificationWebSocket.getInstance(); 